[11/05/99]Ŀ
----     <-- Safedisc Cracking Tutorial by Tola[AmoK] -->     ---Ĵ


 Inhalt - Deutsche Version

    I.  Einleitung

    II. Cracken des Programmes

    III.Schluwort / Thanks & Greetings / Autorkontakt

 Tutorial

    I.  Einleitung

        Kaum hatte ich mein erstes Safedisc Tutorial beendet,
        verffentlichte C-Dilla eine neue Version ihres Kopier-
        schutzes, der eine differenzierte Vorgehensweise er-
        fordert. Dieses Tutorial baut auf dem ersten auf, daher
        werden hier nur die Neuerungen im Kopierschutz erlutert,
        das Basiswissen mt ihr aus dem alten Tutorial beziehen.

    II. Cracken des Programmes

        Das einzige, was bei der neuen Safedisc-Version anders
        gemacht werden mu, ist das reparieren der Importtabelle.
        Ich spare mir lange Vorreden und komme gleich zur Sache.

        Die Safedisc-Funktion zur Berechnung der Funktionsadressen
        der importierten DLLs sieht nun folgendermaen aus:

        PUSH    9413FFBE
        PUSH    0               ;Funktionsnummer
        PUSH    1               ;DLL-Nummer
        CALL    [XXXXXXXX]      ;Aufruf der Safedisc-Funktion
        ADD     ESP,0C

        Die Programmierer bei C-Dilla haben sich etwas ganz be-
        sonderes ausgedacht - die DLL Nummer ist jetzt fr Kernel32-
        Importe nicht mehr 0, sondern 1, bei User32-Importen verhlt
        es sich genau anders herum. Dies sollte also kein groes
        Problem darstellen. Versucht man jedoch, die Importtabelle
        mit dem Algorithmus aus meinem ersten Tutorial zu reparieren,
        wird die Safedisc-Funktion hchtswahrscheinlich versuchen,
        das Programm zum Absturz zu bringen (setzen von EIP auf 0
        oder Zugriff auf ungltige Speicherbereiche). Mit einigen
        Modifikationen des Safedisc-Codes lt sich dieser Bug
        aber beheben. Weiterhin liefert die Funktion nicht mehr
        die falsche Referenz durch ECX+EDX zurck.
        Tracen wir einmal in die Safedisc-Funktion, bis wir folgenden
        Code sehen:

        0177:008F0B69  PUSH      00908958
        0177:008F0B6E  CALL      [KERNEL32!EnterCriticalSection]
        0177:008F0B74  MOV       EAX,[EBP+0C]
        0177:008F0B77  PUSH      EAX
        0177:008F0B78  MOV       ECX,[EBP+08]
        0177:008F0B7B  PUSH      ECX
        0177:008F0B7C  CALL      008EF6C0
        0177:008F0B81  ADD       ESP,04
        0177:008F0B84  PUSH      EAX
        0177:008F0B85  CALL      008EF6A0
        0177:008F0B8A  ADD       ESP,08
        0177:008F0B8D  AND       EAX,0000FFFF
        0177:008F0B92  CMP       EAX,01
        0177:008F0B95  JNZ       008F0D3B
        0177:008F0B9B  JMP       008F0B9E

        An Adresse 8F0B8A finden wir die Adresse der ersten
        falschen Referenz (welche die Adresse der Funktion 0 der
        DLL holt) in ECX. Wir mssen diesen Wert sichern, so
        da wir ihn spter benutzen knnen. Also kopieren wir
        ihn einfach nach EBX, da dieses Register nicht verndert
        wird:

                       CALL      008EF6A0
                       ADD       ESP,08
                       AND       EAX,0000FFFF
                       MOV       EBX,ECX        ;Adresse sichern
                       CMP       EAX,01
                       JNZ       008F0D3B
                       JMP       008F0B9E

        Nun bentigen wir noch die Adresse der importierten
        Funktion. Wir tracen also weiter, bis wir folgende Stelle
        erreichen:

        0177:008F0F5B  MOV       ECX,[EBP-08]
        0177:008F0F5E  PUSH      ECX
        0177:008F0F5F  MOV       EDX,[EBP+08]
        0177:008F0F62  PUSH      EDX
        0177:008F0F63  CALL      008EF720
        0177:008F0F68  ADD       ESP,08
        0177:008F0F6B  MOV       [EBP-04],EAX
        0177:008F0F6E  JMP       008F0F7D

        Die Funktion, die an Adresse 8F0F63 aufgerufen wird,
        liefert die Adresse der importierten Funktion in EAX
        zurck. An dieser Stelle haben wir alles, was wir
        brauchen und knnen die Funktion verlassen:

                       MOV       ECX,[EBP-08]
                       PUSH      ECX
                       MOV       EDX,[EBP+08]
                       PUSH      EDX
                       CALL      008EF720
                       ADD       ESP,08
                       MOV       [EBP-04],EAX
                       LEA       ESP,[EBP+4]    ;ESP mu auf die korrekte
                       RET                      ;Rcksprungadresse zeigen

        Die Funktion mu hier verlassen werden, da es sonst
        zu obengenannten Abstrzen (die wir jedoch zur Not
        mit SoftIce abfangen knnen) kommen kann.
        Diese Vernderungen am Code mssen vorgenommen werden,
        bevor wir einen neuen Algorithmus zum Reparieren der
        Importe starten, schreibe dir die Adressen am besten
        auf.
        Nun liefert die Safedisc-Funktion die korrekte Adresse
        der importierten Funktion in EAX und die Adresse der
        ersten falschen Referenz in EBX. Wir bentigen jedoch
        die Adresse der aktuellen falschen Referenz. Hierzu
        mssen wir die Funktionsnummer mit der Differenz der
        Safedisc-Funktionen multiplizieren und diese Zahl auf
        EBX addieren (Differenz der Funktionen = die Anzahl
        Bytes, die z.B. zwischen dem ersten Befehl der Funktion
        fr die erste Funktion und dem ersten Befehl der Funktion
        fr die zweite Funktion liegen, bei mir 2E Bytes).

        Nun knnen wir wie gewohnt folgenden Algorithmus im
        ADump Speicherbereich assemblieren:

        PUSH        EBX                 ;EBX sichern
        PUSH        9413FFBE
        PUSH        EBX                 ;Funktionsnummer
        PUSH        1                   ;DLL-Nummer (1=Kernel32,0=User32)
        CALL        8F09D0              ;Safedisc-Funktion aufrufen
        ADD         ESP,C
        POP         ECX
        POP         ECX                 ;Funktionsnummer wiederherstellen
        PUSH        EAX                 ;Adresse des Imports sichern
        MOV         EAX,2E              ;Byte-Unterschied zwischen Funktionen
        MUL         ECX                 ;mit Funktionsnr. multiplizieren
        ADD         EBX,EAX             ;EBX zeigt auf Funktion dieser Nr.
        POP         EAX                 ;Adresse des Imports wiederherstellen
        MOV         EDX,49C000          ;.rdata Startadresse
        CMP         DWORD PTR [EDX],EBX ;falsche Referenz suchen
        JE          EIP+D
        INC         EDX
        CMP         EDX,49C000 + 3000 - 3;.rdata Offset + Gre - 3
        JE          EIP+12
        JMP         EIP-D
        SUB         EDX,49C000          ;.rdata Offset subtrahieren
        ADD         EDX,82C7C000        ;ADump Start + 1000
        MOV         DWORD PTR [EDX],EAX ;korrekte Importadresse schreiben
        MOV         EBX,ECX
        INC         EBX                 ;nchste Funktionsnummer
        CMP         EBX,5F              ;letzte Funktion erreicht?
        JBE         82C7B000            ;Jump zum ADump Start
        JMP         EIP

        Dieser Code mag auf den ersten Blick etwas unbersicht-
        lich sein, er erfllt aber auf jeden Fall seinen Zweck.
        Nachdem die Importtabelle repariert wurde, kann die EXE
        natrlich wieder kompatibel gemacht werden (siehe dazu
        das erste Tutorial).

    III.Schluwort / Thanks & Greetings / Autorkontakt

        Mit diesem Wissen sollte es dir jetzt mglich sein,
        ein beliebiges Safedisc-geschtztes Programm in
        zehn bis fnfzehn Minuten zu cracken. Aber freut
        euch nicht zu frh, die nchste Version kommt
        bestimmt ;)

        Greetz und Thanks gehen an
        - alle AmoK Members
        - Black Check fr sein gutes Safedisc Tutorial
        - +Frog's Print fr FrogSice
        - G-RoM, Lorian und Stone fr ProcDump
        - tHeRaiN fr ADump
        - Numega fr SoftIce
        - C-Dilla fr Safedisc
        - Alle, die ich vergessen habe

        Lob und Kritik bitte an:
        tola@gmx.at

        Visit AmoK:
        travel.to/amok
        amok.notrix.de
        amok.mtv.to
